"""
Converts a SeleniumBase Python file into one that uses the Page Object Pattern.

Usage:
        seleniumbase objectify [SELENIUMBASE_PYTHON_FILE].py
Output:
        A modified version of the file where the selectors
        have been replaced with variable names defined in
        "page_objects.py", supporting the Page Object Pattern.
"""

import codecs
import os
import re
import sys

PAGE_OBJECTS_FILE = "page_objects.py"  # Don't change this. It's hard-coded.


def invalid_run_command(shell_command):
    if shell_command == "objectify":
        invalid_objectify_run_command()
    elif shell_command == "inject-objects":
        invalid_inject_objects_run_command()
    elif shell_command == "extract-objects":
        invalid_extract_objects_run_command()
    elif shell_command == "revert-objects":
        invalid_revert_objects_run_command()
    else:
        invalid_objectify_run_command()


def invalid_objectify_run_command():
    exp = "  ** objectify **\n\n"
    exp += "  Usage:\n"
    exp += "         seleniumbase objectify [SELENIUMBASE_PYTHON_FILE]\n"
    exp += "  Options:\n"
    exp += "         -c, --comments  (Add object selectors to the comments.)\n"
    exp += "                         (Default: No added comments.)\n"
    exp += "  Output:\n"
    exp += "         Converts a SeleniumBase Python file into one that uses\n"
    exp += "         the Page Object Pattern by converting page selectors\n"
    exp += '         into objects stored in a "page_objects.py" file that is\n'
    exp += "         autogenerated and stored in the same folder as tests.\n"
    exp += '         (seleniumbase "objectify" has the same outcome as\n'
    exp += '         combining "extract-objects" with "inject-objects")\n'
    raise Exception("INVALID RUN COMMAND!\n\n%s" % exp)


def invalid_inject_objects_run_command():
    exp = "  ** inject-objects **\n\n"
    exp += "  Usage:\n"
    exp += "         seleniumbase inject-objects [SELENIUMBASE_PYTHON_FILE]\n"
    exp += "  Options:\n"
    exp += "         -c, --comments  (Add object selectors to the comments.)\n"
    exp += "                         (Default: No added comments.)\n"
    exp += "  Output:\n"
    exp += '         Takes the page objects found in the "page_objects.py"\n'
    exp += "         file and uses those to replace matching selectors in\n"
    exp += "         the selected seleniumbase Python file.\n"
    raise Exception("INVALID RUN COMMAND!\n\n%s" % exp)


def invalid_extract_objects_run_command():
    exp = "  ** extract-objects **\n\n"
    exp += "  Usage:\n"
    exp += "         seleniumbase extract-objects [SELENIUMBASE_PYTHON_FILE]\n"
    exp += "  Output:\n"
    exp += "         Creates page objects based on selectors found in a\n"
    exp += "         seleniumbase Python file and saves those objects to the\n"
    exp += '         "page_objects.py" file in the same folder as the tests.\n'
    raise Exception("INVALID RUN COMMAND!\n\n%s" % exp)


def invalid_revert_objects_run_command():
    exp = "  ** revert-objects **\n\n"
    exp += "  Usage:\n"
    exp += "         seleniumbase revert-objects [SELENIUMBASE_PYTHON_FILE]\n"
    exp += "  Options:\n"
    exp += "         -c, --comments  (Keep existing comments for the lines.)\n"
    exp += "                         (Default: No comments are kept.)\n"
    exp += "  Output:\n"
    exp += '         Reverts the changes made by "seleniumbase objectify" or\n'
    exp += '         "seleniumbase inject-objects" when run against a\n'
    exp += "         seleniumbase Python file. Objects will get replaced by\n"
    exp += '         selectors stored in the "page_objects.py" file.\n'
    raise Exception("INVALID RUN COMMAND!\n\n%s" % exp)


def remove_extra_slashes(selector):
    if selector.count('\\"') > 0:
        if selector.count('\\"') == selector.count('"'):
            selector = selector.replace('\\"', '"')
        elif selector.count('\\"') == selector[1:-1].count('"') and (
            "'" not in selector[1:-1]
        ):
            selector = "'" + selector[1:-1].replace('\\"', '"') + "'"
        else:
            pass
    if selector.count("\\'") > 0:
        if selector.count("\\'") == selector.count("'"):
            selector = selector.replace("\\'", "'")
        elif selector.count("\\'") == selector[1:-1].count("'") and (
            '"' not in selector[1:-1]
        ):
            selector = '"' + selector[1:-1].replace("\\'", "'") + '"'
        else:
            pass
    return selector


def create_objects_file(selector_list_dict=None):
    data = []
    if selector_list_dict:
        data.append("# -*- coding: utf-8 -*-")
        data.append("# PAGE OBJECTS FILE >>> (autogenerated)")
        data.append("")
        for key in selector_list_dict.keys():
            if key == "None":
                if len(selector_list_dict["None"]) > 0:
                    for pair in selector_list_dict["None"]:
                        data.append("%s = %s" % (pair[0], pair[1]))
                    data.append("")
                else:
                    pass
            else:
                data.append("")
                data.append("class %s(object):" % key)
                for pair in selector_list_dict[key]:
                    data.append("    %s = %s" % (pair[0], pair[1]))
                data.append("")
    else:
        data.append("")
        data.append("class Page(object):")
        data.append('    html = "html"')
        data.append("")
    file_path = PAGE_OBJECTS_FILE
    file = codecs.open(file_path, "w+", "utf-8")
    file.writelines("\r\n".join(data))
    file.close()
    if not selector_list_dict:
        print('\n>>> ["%s"] was created!' % file_path)
    else:
        print('\n>>> ["%s"] was updated!' % file_path)


def scan_objects_file():
    if not os.path.exists(PAGE_OBJECTS_FILE):
        create_objects_file()

    page_selectors = {}
    with open(PAGE_OBJECTS_FILE, "r", encoding="utf-8") as f:
        all_code = f.read()

    var_names = []
    selectors = []
    current_class = "None"
    selector_list_dict = {}  # Key = class name / Values are name-value tuples
    selector_list_dict[current_class] = []
    selector_list_dict["Page"] = []
    code_lines = all_code.split("\n")
    for line in code_lines:
        line = line.rstrip()
        # Handle: class CLASSNAME(object):  OR  class CLASSNAME():
        data = re.match(r"""^(\s*)class\s+([\S]+)\((object|)\):\s*$""", line)
        if data:
            whitespace = data.group(1)
            name = "%s" % data.group(2)
            current_class = name
            selector_list_dict[current_class] = []
            page_selectors["class %s" % name] = "."

        # Handle: SELECTOR_NAME = "SELECTOR"
        data = re.match(r"""^(\s*)(\S+)\s*=\s*([\S\s]+)\s*$""", line)
        if data:
            whitespace = data.group(1)
            name = data.group(2)
            selector = data.group(3)
            selector = remove_extra_slashes(selector)
            page_selectors[name] = selector
            var_names.append(name)
            selectors.append(selector)
            if whitespace == "":
                current_class = "None"
            if (len(selector) > 2 and selector[0] == "'") and (
                selector[-1] == "'" and '"' not in selector[1:-1]
            ):
                selector = '"' + selector[1:-1] + '"'
            if "\\[" in selector or "\\]" in selector or "\\." in selector:
                if selector[0] != "r":
                    selector = "r" + selector
            selector_list_dict[current_class].append((name, selector))

        if "class Page" not in page_selectors.keys():
            page_selectors["class Page"] = "."

    if len(selector_list_dict["Page"]) == 0:
        selector_list_dict["Page"].append(("html", '"html"'))
    return var_names, selectors, selector_list_dict


def optimize_selector(selector):
    if (len(selector) > 2 and selector[0] == "'") and (
        selector[-1] == "'" and '"' not in selector[1:-1]
    ):
        selector = '"' + selector[1:-1] + '"'
    if "\\[" in selector or "\\]" in selector or "\\." in selector:
        if selector[0] != "r":
            selector = "r" + selector
    return selector


def get_next_var_name(existing_names):
    base_name = "css_"
    for i in range(1, 99999):
        new_name = "%s%s" % (base_name, str(i))
        if new_name not in existing_names:
            return new_name
    raise Exception("Out of range! (Selector name generation)")


def process_test_file(
    code_lines, selector_dict=None, object_dict=None, add_comments=False
):

    seleniumbase_lines = []
    page_selectors = []
    changed = []  # The classes of page_objects.py to add to the test import

    for line in code_lines:
        line = line.rstrip()

        # Keep lines with "%s" in them as they were
        if r"%s" in line:
            seleniumbase_lines.append(line)
            continue

        # Handle self.click(SELECTOR)
        if not object_dict:
            data = re.match(
                r"""^(\s*)self\.click"""
                r"""\((r?['"][\S\s]+['"])\)([\S\s]*)"""
                r"""$""",
                line,
            )
        else:
            data = re.match(
                r"""^(\s*)self\.click""" r"""\(([\S]+)\)([\S\s]*)""" r"""$""",
                line,
            )
        if data:
            whitespace = data.group(1)
            selector = "%s" % data.group(2)
            selector = remove_extra_slashes(selector)
            page_selectors.append(selector)
            comments = data.group(3)
            command = """%sself.click(%s)%s""" % (
                whitespace,
                selector,
                comments,
            )
            if selector_dict:
                if add_comments:
                    comments = "  # %s" % selector
                selector = optimize_selector(selector)
                if selector in selector_dict.keys():
                    selector_object = selector_dict[selector]
                    changed.append(selector_object.split(".")[0])
                    command = """%sself.click(%s)%s""" % (
                        whitespace,
                        selector_object,
                        comments,
                    )
            if object_dict:
                if not add_comments:
                    comments = ""
                object_name = selector
                if object_name in object_dict.keys():
                    selector_object = object_dict[object_name]
                    changed.append(object_name.split(".")[0])
                    command = """%sself.click(%s)%s""" % (
                        whitespace,
                        selector_object,
                        comments,
                    )
            seleniumbase_lines.append(command)
            continue

        # Handle self.js_click(SELECTOR)
        if not object_dict:
            data = re.match(
                r"""^(\s*)self\.js_click"""
                r"""\((r?['"][\S\s]+['"])\)([\S\s]*)"""
                r"""$""",
                line,
            )
        else:
            data = re.match(
                r"""^(\s*)self\.js_click"""
                r"""\(([\S]+)\)([\S\s]*)"""
                r"""$""",
                line,
            )
        if data:
            whitespace = data.group(1)
            selector = "%s" % data.group(2)
            selector = remove_extra_slashes(selector)
            page_selectors.append(selector)
            comments = data.group(3)
            command = """%sself.js_click(%s)%s""" % (
                whitespace,
                selector,
                comments,
            )
            if selector_dict:
                if add_comments:
                    comments = "  # %s" % selector
                selector = optimize_selector(selector)
                if selector in selector_dict.keys():
                    selector_object = selector_dict[selector]
                    changed.append(selector_object.split(".")[0])
                    command = """%sself.js_click(%s)%s""" % (
                        whitespace,
                        selector_object,
                        comments,
                    )
            if object_dict:
                if not add_comments:
                    comments = ""
                object_name = selector
                if object_name in object_dict.keys():
                    selector_object = object_dict[object_name]
                    changed.append(object_name.split(".")[0])
                    command = """%sself.js_click(%s)%s""" % (
                        whitespace,
                        selector_object,
                        comments,
                    )
            seleniumbase_lines.append(command)
            continue

        # Handle self.slow_click(SELECTOR)
        if not object_dict:
            data = re.match(
                r"""^(\s*)self\.slow_click"""
                r"""\((r?['"][\S\s]+['"])\)([\S\s]*)"""
                r"""$""",
                line,
            )
        else:
            data = re.match(
                r"""^(\s*)self\.slow_click"""
                r"""\(([\S]+)\)([\S\s]*)"""
                r"""$""",
                line,
            )
        if data:
            whitespace = data.group(1)
            selector = "%s" % data.group(2)
            selector = remove_extra_slashes(selector)
            page_selectors.append(selector)
            comments = data.group(3)
            command = """%sself.slow_click(%s)%s""" % (
                whitespace,
                selector,
                comments,
            )
            if selector_dict:
                if add_comments:
                    comments = "  # %s" % selector
                selector = optimize_selector(selector)
                if selector in selector_dict.keys():
                    selector_object = selector_dict[selector]
                    changed.append(selector_object.split(".")[0])
                    command = """%sself.slow_click(%s)%s""" % (
                        whitespace,
                        selector_object,
                        comments,
                    )
            if object_dict:
                if not add_comments:
                    comments = ""
                object_name = selector
                if object_name in object_dict.keys():
                    selector_object = object_dict[object_name]
                    changed.append(object_name.split(".")[0])
                    command = """%sself.slow_click(%s)%s""" % (
                        whitespace,
                        selector_object,
                        comments,
                    )
            seleniumbase_lines.append(command)
            continue

        # Handle self.double_click(SELECTOR)
        if not object_dict:
            data = re.match(
                r"""^(\s*)self\.double_click"""
                r"""\((r?['"][\S\s]+['"])\)([\S\s]*)"""
                r"""$""",
                line,
            )
        else:
            data = re.match(
                r"""^(\s*)self\.double_click"""
                r"""\(([\S]+)\)([\S\s]*)"""
                r"""$""",
                line,
            )
        if data:
            whitespace = data.group(1)
            selector = "%s" % data.group(2)
            selector = remove_extra_slashes(selector)
            page_selectors.append(selector)
            comments = data.group(3)
            command = """%sself.double_click(%s)%s""" % (
                whitespace,
                selector,
                comments,
            )
            if selector_dict:
                if add_comments:
                    comments = "  # %s" % selector
                selector = optimize_selector(selector)
                if selector in selector_dict.keys():
                    selector_object = selector_dict[selector]
                    changed.append(selector_object.split(".")[0])
                    command = """%sself.double_click(%s)%s""" % (
                        whitespace,
                        selector_object,
                        comments,
                    )
            if object_dict:
                if not add_comments:
                    comments = ""
                object_name = selector
                if object_name in object_dict.keys():
                    selector_object = object_dict[object_name]
                    changed.append(object_name.split(".")[0])
                    command = """%sself.double_click(%s)%s""" % (
                        whitespace,
                        selector_object,
                        comments,
                    )
            seleniumbase_lines.append(command)
            continue

        # Handle self.click_visible_elements(SELECTOR)
        if not object_dict:
            data = re.match(
                r"""^(\s*)self\.click_visible_elements"""
                r"""\((r?['"][\S\s]+['"])\)([\S\s]*)"""
                r"""$""",
                line,
            )
        else:
            data = re.match(
                r"""^(\s*)self\.click_visible_elements"""
                r"""\(([\S]+)\)([\S\s]*)"""
                r"""$""",
                line,
            )
        if data:
            whitespace = data.group(1)
            selector = "%s" % data.group(2)
            selector = remove_extra_slashes(selector)
            page_selectors.append(selector)
            comments = data.group(3)
            command = """%sself.click_visible_elements(%s)%s""" % (
                whitespace,
                selector,
                comments,
            )
            if selector_dict:
                if add_comments:
                    comments = "  # %s" % selector
                selector = optimize_selector(selector)
                if selector in selector_dict.keys():
                    selector_object = selector_dict[selector]
                    changed.append(selector_object.split(".")[0])
                    command = """%sself.click_visible_elements(%s)%s""" % (
                        whitespace,
                        selector_object,
                        comments,
                    )
            if object_dict:
                if not add_comments:
                    comments = ""
                object_name = selector
                if object_name in object_dict.keys():
                    selector_object = object_dict[object_name]
                    changed.append(object_name.split(".")[0])
                    command = """%sself.click_visible_elements(%s)%s""" % (
                        whitespace,
                        selector_object,
                        comments,
                    )
            seleniumbase_lines.append(command)
            continue

        # Handle self.highlight(SELECTOR)
        if not object_dict:
            data = re.match(
                r"""^(\s*)self\.highlight"""
                r"""\((r?['"][\S\s]+['"])\)([\S\s]*)"""
                r"""$""",
                line,
            )
        else:
            data = re.match(
                r"""^(\s*)self\.highlight"""
                r"""\(([\S]+)\)([\S\s]*)"""
                r"""$""",
                line,
            )
        if data:
            whitespace = data.group(1)
            selector = "%s" % data.group(2)
            selector = remove_extra_slashes(selector)
            page_selectors.append(selector)
            comments = data.group(3)
            command = """%sself.highlight(%s)%s""" % (
                whitespace,
                selector,
                comments,
            )
            if selector_dict:
                if add_comments:
                    comments = "  # %s" % selector
                selector = optimize_selector(selector)
                if selector in selector_dict.keys():
                    selector_object = selector_dict[selector]
                    changed.append(selector_object.split(".")[0])
                    command = """%sself.highlight(%s)%s""" % (
                        whitespace,
                        selector_object,
                        comments,
                    )
            if object_dict:
                if not add_comments:
                    comments = ""
                object_name = selector
                if object_name in object_dict.keys():
                    selector_object = object_dict[object_name]
                    changed.append(object_name.split(".")[0])
                    command = """%sself.highlight(%s)%s""" % (
                        whitespace,
                        selector_object,
                        comments,
                    )
            seleniumbase_lines.append(command)
            continue

        # Handle self.highlight_click(SELECTOR)
        if not object_dict:
            data = re.match(
                r"""^(\s*)self\.highlight_click"""
                r"""\((r?['"][\S\s]+['"])\)([\S\s]*)"""
                r"""$""",
                line,
            )
        else:
            data = re.match(
                r"""^(\s*)self\.highlight_click"""
                r"""\(([\S]+)\)([\S\s]*)"""
                r"""$""",
                line,
            )
        if data:
            whitespace = data.group(1)
            selector = "%s" % data.group(2)
            selector = remove_extra_slashes(selector)
            page_selectors.append(selector)
            comments = data.group(3)
            command = """%sself.highlight_click(%s)%s""" % (
                whitespace,
                selector,
                comments,
            )
            if selector_dict:
                if add_comments:
                    comments = "  # %s" % selector
                selector = optimize_selector(selector)
                if selector in selector_dict.keys():
                    selector_object = selector_dict[selector]
                    changed.append(selector_object.split(".")[0])
                    command = """%sself.highlight_click(%s)%s""" % (
                        whitespace,
                        selector_object,
                        comments,
                    )
            if object_dict:
                if not add_comments:
                    comments = ""
                object_name = selector
                if object_name in object_dict.keys():
                    selector_object = object_dict[object_name]
                    changed.append(object_name.split(".")[0])
                    command = """%sself.highlight_click(%s)%s""" % (
                        whitespace,
                        selector_object,
                        comments,
                    )
            seleniumbase_lines.append(command)
            continue

        # Handle self.check_if_unchecked(SELECTOR)
        if not object_dict:
            data = re.match(
                r"""^(\s*)self\.check_if_unchecked"""
                r"""\((r?['"][\S\s]+['"])\)([\S\s]*)"""
                r"""$""",
                line,
            )
        else:
            data = re.match(
                r"""^(\s*)self\.check_if_unchecked"""
                r"""\(([\S]+)\)([\S\s]*)"""
                r"""$""",
                line,
            )
        if data:
            whitespace = data.group(1)
            selector = "%s" % data.group(2)
            selector = remove_extra_slashes(selector)
            page_selectors.append(selector)
            comments = data.group(3)
            command = """%sself.check_if_unchecked(%s)%s""" % (
                whitespace,
                selector,
                comments,
            )
            if selector_dict:
                if add_comments:
                    comments = "  # %s" % selector
                selector = optimize_selector(selector)
                if selector in selector_dict.keys():
                    selector_object = selector_dict[selector]
                    changed.append(selector_object.split(".")[0])
                    command = """%sself.check_if_unchecked(%s)%s""" % (
                        whitespace,
                        selector_object,
                        comments,
                    )
            if object_dict:
                if not add_comments:
                    comments = ""
                object_name = selector
                if object_name in object_dict.keys():
                    selector_object = object_dict[object_name]
                    changed.append(object_name.split(".")[0])
                    command = """%sself.check_if_unchecked(%s)%s""" % (
                        whitespace,
                        selector_object,
                        comments,
                    )
            seleniumbase_lines.append(command)
            continue

        # Handle self.uncheck_if_checked(SELECTOR)
        if not object_dict:
            data = re.match(
                r"""^(\s*)self\.uncheck_if_checked"""
                r"""\((r?['"][\S\s]+['"])\)([\S\s]*)"""
                r"""$""",
                line,
            )
        else:
            data = re.match(
                r"""^(\s*)self\.uncheck_if_checked"""
                r"""\(([\S]+)\)([\S\s]*)"""
                r"""$""",
                line,
            )
        if data:
            whitespace = data.group(1)
            selector = "%s" % data.group(2)
            selector = remove_extra_slashes(selector)
            page_selectors.append(selector)
            comments = data.group(3)
            command = """%sself.uncheck_if_checked(%s)%s""" % (
                whitespace,
                selector,
                comments,
            )
            if selector_dict:
                if add_comments:
                    comments = "  # %s" % selector
                selector = optimize_selector(selector)
                if selector in selector_dict.keys():
                    selector_object = selector_dict[selector]
                    changed.append(selector_object.split(".")[0])
                    command = """%sself.uncheck_if_checked(%s)%s""" % (
                        whitespace,
                        selector_object,
                        comments,
                    )
            if object_dict:
                if not add_comments:
                    comments = ""
                object_name = selector
                if object_name in object_dict.keys():
                    selector_object = object_dict[object_name]
                    changed.append(object_name.split(".")[0])
                    command = """%sself.uncheck_if_checked(%s)%s""" % (
                        whitespace,
                        selector_object,
                        comments,
                    )
            seleniumbase_lines.append(command)
            continue

        # Handle self.select_if_unselected(SELECTOR)
        if not object_dict:
            data = re.match(
                r"""^(\s*)self\.select_if_unselected"""
                r"""\((r?['"][\S\s]+['"])\)([\S\s]*)"""
                r"""$""",
                line,
            )
        else:
            data = re.match(
                r"""^(\s*)self\.select_if_unselected"""
                r"""\(([\S]+)\)([\S\s]*)"""
                r"""$""",
                line,
            )
        if data:
            whitespace = data.group(1)
            selector = "%s" % data.group(2)
            selector = remove_extra_slashes(selector)
            page_selectors.append(selector)
            comments = data.group(3)
            command = """%sself.select_if_unselected(%s)%s""" % (
                whitespace,
                selector,
                comments,
            )
            if selector_dict:
                if add_comments:
                    comments = "  # %s" % selector
                selector = optimize_selector(selector)
                if selector in selector_dict.keys():
                    selector_object = selector_dict[selector]
                    changed.append(selector_object.split(".")[0])
                    command = """%sself.select_if_unselected(%s)%s""" % (
                        whitespace,
                        selector_object,
                        comments,
                    )
            if object_dict:
                if not add_comments:
                    comments = ""
                object_name = selector
                if object_name in object_dict.keys():
                    selector_object = object_dict[object_name]
                    changed.append(object_name.split(".")[0])
                    command = """%sself.select_if_unselected(%s)%s""" % (
                        whitespace,
                        selector_object,
                        comments,
                    )
            seleniumbase_lines.append(command)
            continue

        # Handle self.unselect_if_selected(SELECTOR)
        if not object_dict:
            data = re.match(
                r"""^(\s*)self\.unselect_if_selected"""
                r"""\((r?['"][\S\s]+['"])\)([\S\s]*)"""
                r"""$""",
                line,
            )
        else:
            data = re.match(
                r"""^(\s*)self\.unselect_if_selected"""
                r"""\(([\S]+)\)([\S\s]*)"""
                r"""$""",
                line,
            )
        if data:
            whitespace = data.group(1)
            selector = "%s" % data.group(2)
            selector = remove_extra_slashes(selector)
            page_selectors.append(selector)
            comments = data.group(3)
            command = """%sself.unselect_if_selected(%s)%s""" % (
                whitespace,
                selector,
                comments,
            )
            if selector_dict:
                if add_comments:
                    comments = "  # %s" % selector
                selector = optimize_selector(selector)
                if selector in selector_dict.keys():
                    selector_object = selector_dict[selector]
                    changed.append(selector_object.split(".")[0])
                    command = """%sself.unselect_if_selected(%s)%s""" % (
                        whitespace,
                        selector_object,
                        comments,
                    )
            if object_dict:
                if not add_comments:
                    comments = ""
                object_name = selector
                if object_name in object_dict.keys():
                    selector_object = object_dict[object_name]
                    changed.append(object_name.split(".")[0])
                    command = """%sself.unselect_if_selected(%s)%s""" % (
                        whitespace,
                        selector_object,
                        comments,
                    )
            seleniumbase_lines.append(command)
            continue

        # Handle self.switch_to_frame(SELECTOR)
        if not object_dict:
            data = re.match(
                r"""^(\s*)self\.switch_to_frame"""
                r"""\((r?['"][\S\s]+['"])\)([\S\s]*)"""
                r"""$""",
                line,
            )
        else:
            data = re.match(
                r"""^(\s*)self\.switch_to_frame"""
                r"""\(([\S]+)\)([\S\s]*)"""
                r"""$""",
                line,
            )
        if data:
            whitespace = data.group(1)
            selector = "%s" % data.group(2)
            selector = remove_extra_slashes(selector)
            page_selectors.append(selector)
            comments = data.group(3)
            command = """%sself.switch_to_frame(%s)%s""" % (
                whitespace,
                selector,
                comments,
            )
            if selector_dict:
                if add_comments:
                    comments = "  # %s" % selector
                selector = optimize_selector(selector)
                if selector in selector_dict.keys():
                    selector_object = selector_dict[selector]
                    changed.append(selector_object.split(".")[0])
                    command = """%sself.switch_to_frame(%s)%s""" % (
                        whitespace,
                        selector_object,
                        comments,
                    )
            if object_dict:
                if not add_comments:
                    comments = ""
                object_name = selector
                if object_name in object_dict.keys():
                    selector_object = object_dict[object_name]
                    changed.append(object_name.split(".")[0])
                    command = """%sself.switch_to_frame(%s)%s""" % (
                        whitespace,
                        selector_object,
                        comments,
                    )
            seleniumbase_lines.append(command)
            continue

        # Handle self.switch_to_frame_of_element(SELECTOR)
        if not object_dict:
            data = re.match(
                r"""^(\s*)self\.switch_to_frame_of_element"""
                r"""\((r?['"][\S\s]+['"])\)([\S\s]*)"""
                r"""$""",
                line,
            )
        else:
            data = re.match(
                r"""^(\s*)self\.switch_to_frame_of_element"""
                r"""\(([\S]+)\)([\S\s]*)"""
                r"""$""",
                line,
            )
        if data:
            whitespace = data.group(1)
            selector = "%s" % data.group(2)
            selector = remove_extra_slashes(selector)
            page_selectors.append(selector)
            comments = data.group(3)
            command = """%sself.switch_to_frame_of_element(%s)%s""" % (
                whitespace,
                selector,
                comments,
            )
            if selector_dict:
                if add_comments:
                    comments = "  # %s" % selector
                selector = optimize_selector(selector)
                if selector in selector_dict.keys():
                    selector_object = selector_dict[selector]
                    changed.append(selector_object.split(".")[0])
                    command = """%sself.switch_to_frame_of_element(%s)%s""" % (
                        whitespace,
                        selector_object,
                        comments,
                    )
            if object_dict:
                if not add_comments:
                    comments = ""
                object_name = selector
                if object_name in object_dict.keys():
                    selector_object = object_dict[object_name]
                    changed.append(object_name.split(".")[0])
                    command = """%sself.switch_to_frame_of_element(%s)%s""" % (
                        whitespace,
                        selector_object,
                        comments,
                    )
            seleniumbase_lines.append(command)
            continue

        # Handle self.assert_element(SELECTOR)
        if not object_dict:
            data = re.match(
                r"""^(\s*)self\.assert_element"""
                r"""\((r?['"][\S\s]+['"])\)([\S\s]*)"""
                r"""$""",
                line,
            )
        else:
            data = re.match(
                r"""^(\s*)self\.assert_element"""
                r"""\(([\S]+)\)([\S\s]*)"""
                r"""$""",
                line,
            )
        if data:
            whitespace = data.group(1)
            selector = "%s" % data.group(2)
            selector = remove_extra_slashes(selector)
            page_selectors.append(selector)
            comments = data.group(3)
            command = """%sself.assert_element(%s)%s""" % (
                whitespace,
                selector,
                comments,
            )
            if selector_dict:
                if add_comments:
                    comments = "  # %s" % selector
                selector = optimize_selector(selector)
                if selector in selector_dict.keys():
                    selector_object = selector_dict[selector]
                    changed.append(selector_object.split(".")[0])
                    command = """%sself.assert_element(%s)%s""" % (
                        whitespace,
                        selector_object,
                        comments,
                    )
            if object_dict:
                if not add_comments:
                    comments = ""
                object_name = selector
                if object_name in object_dict.keys():
                    selector_object = object_dict[object_name]
                    changed.append(object_name.split(".")[0])
                    command = """%sself.assert_element(%s)%s""" % (
                        whitespace,
                        selector_object,
                        comments,
                    )
            seleniumbase_lines.append(command)
            continue

        # Handle self.assert_element_*(SELECTOR)  *= present/not_visible/absent
        if not object_dict:
            data = re.match(
                r"""^(\s*)self\.assert_element_(\S*)"""
                r"""\((r?['"][\S\s]+['"])\)([\S\s]*)"""
                r"""$""",
                line,
            )
        else:
            data = re.match(
                r"""^(\s*)self\.assert_element_(\S*)"""
                r"""\(([\S]+)\)([\S\s]*)"""
                r"""$""",
                line,
            )
        if data:
            whitespace = data.group(1)
            by_type = data.group(2)
            selector = "%s" % data.group(3)
            selector = remove_extra_slashes(selector)
            page_selectors.append(selector)
            comments = data.group(4)
            command = """%sself.assert_element_%s(%s)%s""" % (
                whitespace,
                by_type,
                selector,
                comments,
            )
            if selector_dict:
                if add_comments:
                    comments = "  # %s" % selector
                selector = optimize_selector(selector)
                if selector in selector_dict.keys():
                    selector_object = selector_dict[selector]
                    changed.append(selector_object.split(".")[0])
                    command = """%sself.assert_element_%s(%s)%s""" % (
                        whitespace,
                        by_type,
                        selector_object,
                        comments,
                    )
            if object_dict:
                if not add_comments:
                    comments = ""
                object_name = selector
                if object_name in object_dict.keys():
                    selector_object = object_dict[object_name]
                    changed.append(object_name.split(".")[0])
                    command = """%sself.assert_element_%s(%s)%s""" % (
                        whitespace,
                        by_type,
                        selector_object,
                        comments,
                    )
            seleniumbase_lines.append(command)
            continue

        # Handle self.find_element(SELECTOR)
        if not object_dict:
            data = re.match(
                r"""^(\s*)self\.find_element"""
                r"""\((r?['"][\S\s]+['"])\)([\S\s]*)"""
                r"""$""",
                line,
            )
        else:
            data = re.match(
                r"""^(\s*)self\.find_element"""
                r"""\(([\S]+)\)([\S\s]*)"""
                r"""$""",
                line,
            )
        if data:
            whitespace = data.group(1)
            selector = "%s" % data.group(2)
            selector = remove_extra_slashes(selector)
            page_selectors.append(selector)
            comments = data.group(3)
            command = """%sself.find_element(%s)%s""" % (
                whitespace,
                selector,
                comments,
            )
            if selector_dict:
                if add_comments:
                    comments = "  # %s" % selector
                selector = optimize_selector(selector)
                if selector in selector_dict.keys():
                    selector_object = selector_dict[selector]
                    changed.append(selector_object.split(".")[0])
                    command = """%sself.find_element(%s)%s""" % (
                        whitespace,
                        selector_object,
                        comments,
                    )
            if object_dict:
                if not add_comments:
                    comments = ""
                object_name = selector
                if object_name in object_dict.keys():
                    selector_object = object_dict[object_name]
                    changed.append(object_name.split(".")[0])
                    command = """%sself.find_element(%s)%s""" % (
                        whitespace,
                        selector_object,
                        comments,
                    )
            seleniumbase_lines.append(command)
            continue

        # Handle self.get_element(SELECTOR)
        if not object_dict:
            data = re.match(
                r"""^(\s*)self\.get_element"""
                r"""\((r?['"][\S\s]+['"])\)([\S\s]*)"""
                r"""$""",
                line,
            )
        else:
            data = re.match(
                r"""^(\s*)self\.get_element"""
                r"""\(([\S]+)\)([\S\s]*)"""
                r"""$""",
                line,
            )
        if data:
            whitespace = data.group(1)
            selector = "%s" % data.group(2)
            selector = remove_extra_slashes(selector)
            page_selectors.append(selector)
            comments = data.group(3)
            command = """%sself.get_element(%s)%s""" % (
                whitespace,
                selector,
                comments,
            )
            if selector_dict:
                if add_comments:
                    comments = "  # %s" % selector
                selector = optimize_selector(selector)
                if selector in selector_dict.keys():
                    selector_object = selector_dict[selector]
                    changed.append(selector_object.split(".")[0])
                    command = """%sself.get_element(%s)%s""" % (
                        whitespace,
                        selector_object,
                        comments,
                    )
            if object_dict:
                if not add_comments:
                    comments = ""
                object_name = selector
                if object_name in object_dict.keys():
                    selector_object = object_dict[object_name]
                    changed.append(object_name.split(".")[0])
                    command = """%sself.get_element(%s)%s""" % (
                        whitespace,
                        selector_object,
                        comments,
                    )
            seleniumbase_lines.append(command)
            continue

        # Handle self.wait_for_element(SELECTOR)
        if not object_dict:
            data = re.match(
                r"""^(\s*)self\.wait_for_element"""
                r"""\((r?['"][\S\s]+['"])\)([\S\s]*)"""
                r"""$""",
                line,
            )
        else:
            data = re.match(
                r"""^(\s*)self\.wait_for_element"""
                r"""\(([\S]+)\)([\S\s]*)"""
                r"""$""",
                line,
            )
        if data:
            whitespace = data.group(1)
            selector = "%s" % data.group(2)
            selector = remove_extra_slashes(selector)
            page_selectors.append(selector)
            comments = data.group(3)
            command = """%sself.wait_for_element(%s)%s""" % (
                whitespace,
                selector,
                comments,
            )
            if selector_dict:
                if add_comments:
                    comments = "  # %s" % selector
                selector = optimize_selector(selector)
                if selector in selector_dict.keys():
                    selector_object = selector_dict[selector]
                    changed.append(selector_object.split(".")[0])
                    command = """%sself.wait_for_element(%s)%s""" % (
                        whitespace,
                        selector_object,
                        comments,
                    )
            if object_dict:
                if not add_comments:
                    comments = ""
                object_name = selector
                if object_name in object_dict.keys():
                    selector_object = object_dict[object_name]
                    changed.append(object_name.split(".")[0])
                    command = """%sself.wait_for_element(%s)%s""" % (
                        whitespace,
                        selector_object,
                        comments,
                    )
            seleniumbase_lines.append(command)
            continue

        # Handle self.wait_for_element_*(SELECTOR)  * = present/visible
        if not object_dict:
            data = re.match(
                r"""^(\s*)self\.wait_for_element_(\S*)"""
                r"""\((r?['"][\S\s]+['"])\)([\S\s]*)"""
                r"""$""",
                line,
            )
        else:
            data = re.match(
                r"""^(\s*)self\.wait_for_element_(\S*)"""
                r"""\(([\S]+)\)([\S\s]*)"""
                r"""$""",
                line,
            )
        if data:
            whitespace = data.group(1)
            by_type = data.group(2)
            selector = "%s" % data.group(3)
            selector = remove_extra_slashes(selector)
            page_selectors.append(selector)
            comments = data.group(4)
            command = """%sself.wait_for_element_%s(%s)%s""" % (
                whitespace,
                by_type,
                selector,
                comments,
            )
            if selector_dict:
                if add_comments:
                    comments = "  # %s" % selector
                selector = optimize_selector(selector)
                if selector in selector_dict.keys():
                    selector_object = selector_dict[selector]
                    changed.append(selector_object.split(".")[0])
                    command = """%sself.wait_for_element_%s(%s)%s""" % (
                        whitespace,
                        by_type,
                        selector_object,
                        comments,
                    )
            if object_dict:
                if not add_comments:
                    comments = ""
                object_name = selector
                if object_name in object_dict.keys():
                    selector_object = object_dict[object_name]
                    changed.append(object_name.split(".")[0])
                    command = """%sself.wait_for_element_%s(%s)%s""" % (
                        whitespace,
                        by_type,
                        selector_object,
                        comments,
                    )
            seleniumbase_lines.append(command)
            continue

        # Handle self.update_text(SELECTOR, TEXT)
        if not object_dict:
            data = re.match(
                r"""^(\s*)self\.update_text"""
                r"""\((r?['"][\S\s]+['"]),\s?([\S\s]+)\)([\S\s]*)"""
                r"""$""",
                line,
            )
        else:
            data = re.match(
                r"""^(\s*)self\.update_text"""
                r"""\(([\S]+),\s?([\S\s]+)\)([\S\s]*)"""
                r"""$""",
                line,
            )
        if data:
            whitespace = data.group(1)
            selector = "%s" % data.group(2)
            selector = remove_extra_slashes(selector)
            page_selectors.append(selector)
            text = data.group(3)
            comments = data.group(4)
            command = """%sself.update_text(%s, %s)%s""" % (
                whitespace,
                selector,
                text,
                comments,
            )
            if selector_dict:
                if add_comments:
                    comments = "  # %s" % selector
                selector = optimize_selector(selector)
                if selector in selector_dict.keys():
                    selector_object = selector_dict[selector]
                    changed.append(selector_object.split(".")[0])
                    command = """%sself.update_text(%s, %s)%s""" % (
                        whitespace,
                        selector_object,
                        text,
                        comments,
                    )
            if object_dict:
                if not add_comments:
                    comments = ""
                object_name = selector
                if object_name in object_dict.keys():
                    selector_object = object_dict[object_name]
                    changed.append(object_name.split(".")[0])
                    command = """%sself.update_text(%s, %s)%s""" % (
                        whitespace,
                        selector_object,
                        text,
                        comments,
                    )
            seleniumbase_lines.append(command)
            continue

        # Handle self.type(SELECTOR, TEXT)
        if not object_dict:
            data = re.match(
                r"""^(\s*)self\.type"""
                r"""\((r?['"][\S\s]+['"]),\s?([\S\s]+)\)([\S\s]*)"""
                r"""$""",
                line,
            )
        else:
            data = re.match(
                r"""^(\s*)self\.type"""
                r"""\(([\S]+),\s?([\S\s]+)\)([\S\s]*)"""
                r"""$""",
                line,
            )
        if data:
            whitespace = data.group(1)
            selector = "%s" % data.group(2)
            selector = remove_extra_slashes(selector)
            page_selectors.append(selector)
            text = data.group(3)
            comments = data.group(4)
            command = """%sself.type(%s, %s)%s""" % (
                whitespace,
                selector,
                text,
                comments,
            )
            if selector_dict:
                if add_comments:
                    comments = "  # %s" % selector
                selector = optimize_selector(selector)
                if selector in selector_dict.keys():
                    selector_object = selector_dict[selector]
                    changed.append(selector_object.split(".")[0])
                    command = """%sself.type(%s, %s)%s""" % (
                        whitespace,
                        selector_object,
                        text,
                        comments,
                    )
            if object_dict:
                if not add_comments:
                    comments = ""
                object_name = selector
                if object_name in object_dict.keys():
                    selector_object = object_dict[object_name]
                    changed.append(object_name.split(".")[0])
                    command = """%sself.type(%s, %s)%s""" % (
                        whitespace,
                        selector_object,
                        text,
                        comments,
                    )
            seleniumbase_lines.append(command)
            continue

        # Handle self.input(SELECTOR, TEXT)
        if not object_dict:
            data = re.match(
                r"""^(\s*)self\.input"""
                r"""\((r?['"][\S\s]+['"]),\s?([\S\s]+)\)([\S\s]*)"""
                r"""$""",
                line,
            )
        else:
            data = re.match(
                r"""^(\s*)self\.input"""
                r"""\(([\S]+),\s?([\S\s]+)\)([\S\s]*)"""
                r"""$""",
                line,
            )
        if data:
            whitespace = data.group(1)
            selector = "%s" % data.group(2)
            selector = remove_extra_slashes(selector)
            page_selectors.append(selector)
            text = data.group(3)
            comments = data.group(4)
            command = """%sself.input(%s, %s)%s""" % (
                whitespace,
                selector,
                text,
                comments,
            )
            if selector_dict:
                if add_comments:
                    comments = "  # %s" % selector
                selector = optimize_selector(selector)
                if selector in selector_dict.keys():
                    selector_object = selector_dict[selector]
                    changed.append(selector_object.split(".")[0])
                    command = """%sself.input(%s, %s)%s""" % (
                        whitespace,
                        selector_object,
                        text,
                        comments,
                    )
            if object_dict:
                if not add_comments:
                    comments = ""
                object_name = selector
                if object_name in object_dict.keys():
                    selector_object = object_dict[object_name]
                    changed.append(object_name.split(".")[0])
                    command = """%sself.input(%s, %s)%s""" % (
                        whitespace,
                        selector_object,
                        text,
                        comments,
                    )
            seleniumbase_lines.append(command)
            continue

        # Handle self.write(SELECTOR, TEXT)
        if not object_dict:
            data = re.match(
                r"""^(\s*)self\.write"""
                r"""\((r?['"][\S\s]+['"]),\s?([\S\s]+)\)([\S\s]*)"""
                r"""$""",
                line,
            )
        else:
            data = re.match(
                r"""^(\s*)self\.write"""
                r"""\(([\S]+),\s?([\S\s]+)\)([\S\s]*)"""
                r"""$""",
                line,
            )
        if data:
            whitespace = data.group(1)
            selector = "%s" % data.group(2)
            selector = remove_extra_slashes(selector)
            page_selectors.append(selector)
            text = data.group(3)
            comments = data.group(4)
            command = """%sself.write(%s, %s)%s""" % (
                whitespace,
                selector,
                text,
                comments,
            )
            if selector_dict:
                if add_comments:
                    comments = "  # %s" % selector
                selector = optimize_selector(selector)
                if selector in selector_dict.keys():
                    selector_object = selector_dict[selector]
                    changed.append(selector_object.split(".")[0])
                    command = """%sself.write(%s, %s)%s""" % (
                        whitespace,
                        selector_object,
                        text,
                        comments,
                    )
            if object_dict:
                if not add_comments:
                    comments = ""
                object_name = selector
                if object_name in object_dict.keys():
                    selector_object = object_dict[object_name]
                    changed.append(object_name.split(".")[0])
                    command = """%sself.write(%s, %s)%s""" % (
                        whitespace,
                        selector_object,
                        text,
                        comments,
                    )
            seleniumbase_lines.append(command)
            continue

        # Handle self.add_text(SELECTOR, TEXT)
        if not object_dict:
            data = re.match(
                r"""^(\s*)self\.add_text"""
                r"""\((r?['"][\S\s]+['"]),\s?([\S\s]+)\)([\S\s]*)"""
                r"""$""",
                line,
            )
        else:
            data = re.match(
                r"""^(\s*)self\.add_text"""
                r"""\(([\S]+),\s?([\S\s]+)\)([\S\s]*)"""
                r"""$""",
                line,
            )
        if data:
            whitespace = data.group(1)
            selector = "%s" % data.group(2)
            selector = remove_extra_slashes(selector)
            page_selectors.append(selector)
            text = data.group(3)
            comments = data.group(4)
            command = """%sself.add_text(%s, %s)%s""" % (
                whitespace,
                selector,
                text,
                comments,
            )
            if selector_dict:
                if add_comments:
                    comments = "  # %s" % selector
                selector = optimize_selector(selector)
                if selector in selector_dict.keys():
                    selector_object = selector_dict[selector]
                    changed.append(selector_object.split(".")[0])
                    command = """%sself.add_text(%s, %s)%s""" % (
                        whitespace,
                        selector_object,
                        text,
                        comments,
                    )
            if object_dict:
                if not add_comments:
                    comments = ""
                object_name = selector
                if object_name in object_dict.keys():
                    selector_object = object_dict[object_name]
                    changed.append(object_name.split(".")[0])
                    command = """%sself.add_text(%s, %s)%s""" % (
                        whitespace,
                        selector_object,
                        text,
                        comments,
                    )
            seleniumbase_lines.append(command)
            continue

        # Handle self.send_keys(SELECTOR, TEXT)
        if not object_dict:
            data = re.match(
                r"""^(\s*)self\.send_keys"""
                r"""\((r?['"][\S\s]+['"]),\s?([\S\s]+)\)([\S\s]*)"""
                r"""$""",
                line,
            )
        else:
            data = re.match(
                r"""^(\s*)self\.send_keys"""
                r"""\(([\S]+),\s?([\S\s]+)\)([\S\s]*)"""
                r"""$""",
                line,
            )
        if data:
            whitespace = data.group(1)
            selector = "%s" % data.group(2)
            selector = remove_extra_slashes(selector)
            page_selectors.append(selector)
            text = data.group(3)
            comments = data.group(4)
            command = """%sself.send_keys(%s, %s)%s""" % (
                whitespace,
                selector,
                text,
                comments,
            )
            if selector_dict:
                if add_comments:
                    comments = "  # %s" % selector
                selector = optimize_selector(selector)
                if selector in selector_dict.keys():
                    selector_object = selector_dict[selector]
                    changed.append(selector_object.split(".")[0])
                    command = """%sself.send_keys(%s, %s)%s""" % (
                        whitespace,
                        selector_object,
                        text,
                        comments,
                    )
            if object_dict:
                if not add_comments:
                    comments = ""
                object_name = selector
                if object_name in object_dict.keys():
                    selector_object = object_dict[object_name]
                    changed.append(object_name.split(".")[0])
                    command = """%sself.send_keys(%s, %s)%s""" % (
                        whitespace,
                        selector_object,
                        text,
                        comments,
                    )
            seleniumbase_lines.append(command)
            continue

        # Handle self.set_value(SELECTOR, TEXT)
        if not object_dict:
            data = re.match(
                r"""^(\s*)self\.set_value"""
                r"""\((r?['"][\S\s]+['"]),\s?([\S\s]+)\)([\S\s]*)"""
                r"""$""",
                line,
            )
        else:
            data = re.match(
                r"""^(\s*)self\.set_value"""
                r"""\(([\S]+),\s?([\S\s]+)\)([\S\s]*)"""
                r"""$""",
                line,
            )
        if data:
            whitespace = data.group(1)
            selector = "%s" % data.group(2)
            selector = remove_extra_slashes(selector)
            page_selectors.append(selector)
            text = data.group(3)
            comments = data.group(4)
            command = """%sself.set_value(%s, %s)%s""" % (
                whitespace,
                selector,
                text,
                comments,
            )
            if selector_dict:
                if add_comments:
                    comments = "  # %s" % selector
                selector = optimize_selector(selector)
                if selector in selector_dict.keys():
                    selector_object = selector_dict[selector]
                    changed.append(selector_object.split(".")[0])
                    command = """%sself.set_value(%s, %s)%s""" % (
                        whitespace,
                        selector_object,
                        text,
                        comments,
                    )
            if object_dict:
                if not add_comments:
                    comments = ""
                object_name = selector
                if object_name in object_dict.keys():
                    selector_object = object_dict[object_name]
                    changed.append(object_name.split(".")[0])
                    command = """%sself.set_value(%s, %s)%s""" % (
                        whitespace,
                        selector_object,
                        text,
                        comments,
                    )
            seleniumbase_lines.append(command)
            continue

        # Handle self.drag_and_drop(SELECTOR, SELECTOR)
        if not object_dict:
            data = re.match(
                r"""^(\s*)self\.drag_and_drop"""
                r"""\((r?['"][\S\s]+['"]),\s?([\S\s]+)\)([\S\s]*)"""
                r"""$""",
                line,
            )
        else:
            data = re.match(
                r"""^(\s*)self\.drag_and_drop"""
                r"""\(([\S]+),\s?([\S]+)\)([\S\s]*)"""
                r"""$""",
                line,
            )
        if data:
            whitespace = data.group(1)
            selector1 = "%s" % data.group(2)
            selector1 = remove_extra_slashes(selector1)
            page_selectors.append(selector1)
            selector2 = "%s" % data.group(3)
            selector2 = remove_extra_slashes(selector2)
            page_selectors.append(selector2)
            comments = data.group(4)
            command = """%sself.drag_and_drop(%s, %s)%s""" % (
                whitespace,
                selector1,
                selector2,
                comments,
            )
            if selector_dict:
                if add_comments:
                    comments = "  # %s" % selector
                selector1 = optimize_selector(selector1)
                selector2 = optimize_selector(selector2)
                if selector1 in selector_dict.keys() and (
                    selector2 in selector_dict.keys()
                ):
                    selector_object1 = selector_dict[selector1]
                    selector_object2 = selector_dict[selector2]
                    changed.append(selector_object1.split(".")[0])
                    changed.append(selector_object2.split(".")[0])
                    command = """%sself.drag_and_drop(%s, %s)%s""" % (
                        whitespace,
                        selector_object1,
                        selector_object2,
                        comments,
                    )
            if object_dict:
                if not add_comments:
                    comments = ""
                object_name1 = selector1
                object_name2 = selector2
                if object_name1 in object_dict.keys() and (
                    object_name2 in object_dict.keys()
                ):
                    selector_object1 = object_dict[object_name1]
                    selector_object2 = object_dict[object_name2]
                    changed.append(object_name1.split(".")[0])
                    changed.append(object_name2.split(".")[0])
                    command = """%sself.drag_and_drop(%s, %s)%s""" % (
                        whitespace,
                        selector_object1,
                        selector_object2,
                        comments,
                    )
            seleniumbase_lines.append(command)
            continue

        # Handle self.hover_and_click(SELECTOR, SELECTOR)
        if not object_dict:
            data = re.match(
                r"""^(\s*)self\.hover_and_click"""
                r"""\((r?['"][\S\s]+['"]),\s?([\S\s]+)\)([\S\s]*)"""
                r"""$""",
                line,
            )
        else:
            data = re.match(
                r"""^(\s*)self\.hover_and_click"""
                r"""\(([\S]+),\s?([\S]+)\)([\S\s]*)"""
                r"""$""",
                line,
            )
        if data:
            whitespace = data.group(1)
            selector1 = "%s" % data.group(2)
            selector1 = remove_extra_slashes(selector1)
            page_selectors.append(selector1)
            selector2 = "%s" % data.group(3)
            selector2 = remove_extra_slashes(selector2)
            page_selectors.append(selector2)
            comments = data.group(4)
            command = """%sself.hover_and_click(%s, %s)%s""" % (
                whitespace,
                selector1,
                selector2,
                comments,
            )
            if selector_dict:
                if add_comments:
                    comments = "  # %s" % selector
                selector1 = optimize_selector(selector1)
                selector2 = optimize_selector(selector2)
                if selector1 in selector_dict.keys() and (
                    selector2 in selector_dict.keys()
                ):
                    selector_object1 = selector_dict[selector1]
                    selector_object2 = selector_dict[selector2]
                    changed.append(selector_object1.split(".")[0])
                    changed.append(selector_object2.split(".")[0])
                    command = """%sself.hover_and_click(%s, %s)%s""" % (
                        whitespace,
                        selector_object1,
                        selector_object2,
                        comments,
                    )
            if object_dict:
                if not add_comments:
                    comments = ""
                object_name1 = selector1
                object_name2 = selector2
                if object_name1 in object_dict.keys() and (
                    object_name2 in object_dict.keys()
                ):
                    selector_object1 = object_dict[object_name1]
                    selector_object2 = object_dict[object_name2]
                    changed.append(object_name1.split(".")[0])
                    changed.append(object_name2.split(".")[0])
                    command = """%sself.hover_and_click(%s, %s)%s""" % (
                        whitespace,
                        selector_object1,
                        selector_object2,
                        comments,
                    )
            seleniumbase_lines.append(command)
            continue

        # Handle self.press_*_arrow(SELECTOR)
        if not object_dict:
            data = re.match(
                r"""^(\s*)self\.press_(\S*)_arrow"""
                r"""\((r?['"][\S\s]+['"])\)([\S\s]*)"""
                r"""$""",
                line,
            )
        else:
            data = re.match(
                r"""^(\s*)self\.press_(\S*)_arrow"""
                r"""\(([\S]+)\)([\S\s]*)"""
                r"""$""",
                line,
            )
        if data:
            whitespace = data.group(1)
            arrow = "%s" % data.group(2)
            selector = "%s" % data.group(3)
            selector = remove_extra_slashes(selector)
            page_selectors.append(selector)
            comments = data.group(4)
            command = """%sself.press_%s_arrow(%s)%s""" % (
                whitespace,
                arrow,
                selector,
                comments,
            )
            if selector_dict:
                if add_comments:
                    comments = "  # %s" % selector
                selector = optimize_selector(selector)
                if selector in selector_dict.keys():
                    selector_object = selector_dict[selector]
                    changed.append(selector_object.split(".")[0])
                    command = """%sself.press_%s_arrow(%s)%s""" % (
                        whitespace,
                        arrow,
                        selector_object,
                        comments,
                    )
            if object_dict:
                if not add_comments:
                    comments = ""
                object_name = selector
                if object_name in object_dict.keys():
                    selector_object = object_dict[object_name]
                    changed.append(object_name.split(".")[0])
                    command = """%sself.press_%s_arrow(%s)%s""" % (
                        whitespace,
                        arrow,
                        selector_object,
                        comments,
                    )
            seleniumbase_lines.append(command)
            continue

        # Handle self.press_*_arrow(SELECTOR, TIMES)
        if not object_dict:
            data = re.match(
                r"""^(\s*)self\.press_(\S*)_arrow"""
                r"""\((r?['"][\S\s]+['"]),\s?([\S\s]+)\)([\S\s]*)"""
                r"""$""",
                line,
            )
        else:
            data = re.match(
                r"""^(\s*)self\.press_(\S*)_arrow"""
                r"""\(([\S]+),\s?([\S\s]+)\)([\S\s]*)"""
                r"""$""",
                line,
            )
        if data:
            whitespace = data.group(1)
            arrow = "%s" % data.group(2)
            selector = "%s" % data.group(3)
            selector = remove_extra_slashes(selector)
            page_selectors.append(selector)
            times = data.group(4)
            comments = data.group(5)
            command = """%sself.press_%s_arrow(%s, %s)%s""" % (
                whitespace,
                arrow,
                selector,
                times,
                comments,
            )
            if selector_dict:
                if add_comments:
                    comments = "  # %s" % selector
                selector = optimize_selector(selector)
                if selector in selector_dict.keys():
                    selector_object = selector_dict[selector]
                    changed.append(selector_object.split(".")[0])
                    command = """%sself.press_%s_arrow(%s, %s)%s""" % (
                        whitespace,
                        arrow,
                        selector_object,
                        times,
                        comments,
                    )
            if object_dict:
                if not add_comments:
                    comments = ""
                object_name = selector
                if object_name in object_dict.keys():
                    selector_object = object_dict[object_name]
                    changed.append(object_name.split(".")[0])
                    command = """%sself.press_%s_arrow(%s, %s)%s""" % (
                        whitespace,
                        arrow,
                        selector_object,
                        times,
                        comments,
                    )
            seleniumbase_lines.append(command)
            continue

        # Handle self.assert_text(TEXT, SELECTOR)
        if not object_dict:
            data = re.match(
                r"""^(\s*)self\.assert_text"""
                r"""\(([\S\s]+),\s?(r?['"][\S\s]+['"])\)([\S\s]*)"""
                r"""$""",
                line,
            )
        else:
            data = re.match(
                r"""^(\s*)self\.assert_text"""
                r"""\(([\S\s]+),\s?([\S]+)\)([\S\s]*)"""
                r"""$""",
                line,
            )
        if data:
            whitespace = data.group(1)
            text = data.group(2)
            selector = "%s" % data.group(3)
            selector = remove_extra_slashes(selector)
            page_selectors.append(selector)
            comments = data.group(4)
            command = """%sself.assert_text(%s, %s)%s""" % (
                whitespace,
                text,
                selector,
                comments,
            )
            if selector_dict:
                if add_comments:
                    comments = "  # %s" % selector
                selector = optimize_selector(selector)
                if selector in selector_dict.keys():
                    selector_object = selector_dict[selector]
                    changed.append(selector_object.split(".")[0])
                    command = """%sself.assert_text(%s, %s)%s""" % (
                        whitespace,
                        text,
                        selector_object,
                        comments,
                    )
            if object_dict:
                if not add_comments:
                    comments = ""
                object_name = selector
                if object_name in object_dict.keys():
                    selector_object = object_dict[object_name]
                    changed.append(object_name.split(".")[0])
                    command = """%sself.assert_text(%s, %s)%s""" % (
                        whitespace,
                        text,
                        selector_object,
                        comments,
                    )
            seleniumbase_lines.append(command)
            continue

        # Handle self.assert_exact_text(TEXT, SELECTOR)
        if not object_dict:
            data = re.match(
                r"""^(\s*)self\.assert_exact_text"""
                r"""\(([\S\s]+),\s?(r?['"][\S\s]+['"])\)([\S\s]*)"""
                r"""$""",
                line,
            )
        else:
            data = re.match(
                r"""^(\s*)self\.assert_exact_text"""
                r"""\(([\S\s]+),\s?([\S]+)\)([\S\s]*)"""
                r"""$""",
                line,
            )
        if data:
            whitespace = data.group(1)
            text = data.group(2)
            selector = "%s" % data.group(3)
            selector = remove_extra_slashes(selector)
            page_selectors.append(selector)
            comments = data.group(4)
            command = """%sself.assert_exact_text(%s, %s)%s""" % (
                whitespace,
                text,
                selector,
                comments,
            )
            if selector_dict:
                if add_comments:
                    comments = "  # %s" % selector
                selector = optimize_selector(selector)
                if selector in selector_dict.keys():
                    selector_object = selector_dict[selector]
                    changed.append(selector_object.split(".")[0])
                    command = """%sself.assert_exact_text(%s, %s)%s""" % (
                        whitespace,
                        text,
                        selector_object,
                        comments,
                    )
            if object_dict:
                if not add_comments:
                    comments = ""
                object_name = selector
                if object_name in object_dict.keys():
                    selector_object = object_dict[object_name]
                    changed.append(object_name.split(".")[0])
                    command = """%sself.assert_exact_text(%s, %s)%s""" % (
                        whitespace,
                        text,
                        selector_object,
                        comments,
                    )
            seleniumbase_lines.append(command)
            continue

        # Handle self.find_text(TEXT, SELECTOR)
        if not object_dict:
            data = re.match(
                r"""^(\s*)self\.find_text"""
                r"""\(([\S\s]+),\s?(r?['"][\S\s]+['"])\)([\S\s]*)"""
                r"""$""",
                line,
            )
        else:
            data = re.match(
                r"""^(\s*)self\.find_text"""
                r"""\(([\S\s]+),\s?([\S]+)\)([\S\s]*)"""
                r"""$""",
                line,
            )
        if data:
            whitespace = data.group(1)
            text = data.group(2)
            selector = "%s" % data.group(3)
            selector = remove_extra_slashes(selector)
            page_selectors.append(selector)
            comments = data.group(4)
            command = """%sself.find_text(%s, %s)%s""" % (
                whitespace,
                text,
                selector,
                comments,
            )
            if selector_dict:
                if add_comments:
                    comments = "  # %s" % selector
                selector = optimize_selector(selector)
                if selector in selector_dict.keys():
                    selector_object = selector_dict[selector]
                    changed.append(selector_object.split(".")[0])
                    command = """%sself.find_text(%s, %s)%s""" % (
                        whitespace,
                        text,
                        selector_object,
                        comments,
                    )
            if object_dict:
                if not add_comments:
                    comments = ""
                object_name = selector
                if object_name in object_dict.keys():
                    selector_object = object_dict[object_name]
                    changed.append(object_name.split(".")[0])
                    command = """%sself.find_text(%s, %s)%s""" % (
                        whitespace,
                        text,
                        selector_object,
                        comments,
                    )
            seleniumbase_lines.append(command)
            continue

        # Handle if/elif self.is_text_*(TEXT, SELECTOR):  * = present/visible
        if not object_dict:
            data = re.match(
                r"""^(\s*)(\S*)\sself\.is_text_(\S*)"""
                r"""\(([\S\s]+),\s?(r?['"][\S\s]+['"])\):([\S\s]*)"""
                r"""$""",
                line,
            )
        else:
            data = re.match(
                r"""^(\s*)(\S*)\sself\.is_text_(\S*)"""
                r"""\(([\S\s]+),\s?([\S]+)\):([\S\s]*)"""
                r"""$""",
                line,
            )
        if data:
            whitespace = data.group(1)
            if_type = data.group(2)
            by_type = data.group(3)
            text = data.group(4)
            selector = "%s" % data.group(5)
            selector = remove_extra_slashes(selector)
            page_selectors.append(selector)
            comments = data.group(6)
            command = """%s%s self.is_text_%s(%s, %s):%s""" % (
                whitespace,
                if_type,
                by_type,
                text,
                selector,
                comments,
            )
            if selector_dict:
                if add_comments:
                    comments = "  # %s" % selector
                selector = optimize_selector(selector)
                if selector in selector_dict.keys():
                    selector_object = selector_dict[selector]
                    changed.append(selector_object.split(".")[0])
                    command = """%s%s self.is_text_%s(%s, %s):%s""" % (
                        whitespace,
                        if_type,
                        by_type,
                        text,
                        selector_object,
                        comments,
                    )
            if object_dict:
                if not add_comments:
                    comments = ""
                object_name = selector
                if object_name in object_dict.keys():
                    selector_object = object_dict[object_name]
                    changed.append(object_name.split(".")[0])
                    command = """%s%s self.is_text_%s(%s, %s):%s""" % (
                        whitespace,
                        if_type,
                        by_type,
                        text,
                        selector_object,
                        comments,
                    )
            seleniumbase_lines.append(command)
            continue

        # Handle self.wait_for_text(TEXT, SELECTOR)
        if not object_dict:
            data = re.match(
                r"""^(\s*)self\.wait_for_text"""
                r"""\(([\S\s]+),\s?(r?['"][\S\s]+['"])\)([\S\s]*)"""
                r"""$""",
                line,
            )
        else:
            data = re.match(
                r"""^(\s*)self\.wait_for_text"""
                r"""\(([\S\s]+),\s?([\S]+)\)([\S\s]*)"""
                r"""$""",
                line,
            )
        if data:
            whitespace = data.group(1)
            text = data.group(2)
            selector = "%s" % data.group(3)
            selector = remove_extra_slashes(selector)
            page_selectors.append(selector)
            comments = data.group(4)
            command = """%sself.wait_for_text(%s, %s)%s""" % (
                whitespace,
                text,
                selector,
                comments,
            )
            if selector_dict:
                if add_comments:
                    comments = "  # %s" % selector
                selector = optimize_selector(selector)
                if selector in selector_dict.keys():
                    selector_object = selector_dict[selector]
                    changed.append(selector_object.split(".")[0])
                    command = """%sself.wait_for_text(%s, %s)%s""" % (
                        whitespace,
                        text,
                        selector_object,
                        comments,
                    )
            if object_dict:
                if not add_comments:
                    comments = ""
                object_name = selector
                if object_name in object_dict.keys():
                    selector_object = object_dict[object_name]
                    changed.append(object_name.split(".")[0])
                    command = """%sself.wait_for_text(%s, %s)%s""" % (
                        whitespace,
                        text,
                        selector_object,
                        comments,
                    )
            seleniumbase_lines.append(command)
            continue

        # Handle self.wait_for_text_visible(TEXT, SELECTOR)
        if not object_dict:
            data = re.match(
                r"""^(\s*)self\.wait_for_text_visible"""
                r"""\(([\S\s]+),\s?(r?['"][\S\s]+['"])\)([\S\s]*)"""
                r"""$""",
                line,
            )
        else:
            data = re.match(
                r"""^(\s*)self\.wait_for_text_visible"""
                r"""\(([\S\s]+),\s?([\S]+)\)([\S\s]*)"""
                r"""$""",
                line,
            )
        if data:
            whitespace = data.group(1)
            text = data.group(2)
            selector = "%s" % data.group(3)
            selector = remove_extra_slashes(selector)
            page_selectors.append(selector)
            comments = data.group(4)
            command = """%sself.wait_for_text(%s, %s)%s""" % (
                whitespace,
                text,
                selector,
                comments,
            )
            if selector_dict:
                if add_comments:
                    comments = "  # %s" % selector
                selector = optimize_selector(selector)
                if selector in selector_dict.keys():
                    selector_object = selector_dict[selector]
                    changed.append(selector_object.split(".")[0])
                    command = """%sself.wait_for_text(%s, %s)%s""" % (
                        whitespace,
                        text,
                        selector_object,
                        comments,
                    )
            if object_dict:
                if not add_comments:
                    comments = ""
                object_name = selector
                if object_name in object_dict.keys():
                    selector_object = object_dict[object_name]
                    changed.append(object_name.split(".")[0])
                    command = """%sself.wait_for_text(%s, %s)%s""" % (
                        whitespace,
                        text,
                        selector_object,
                        comments,
                    )
            seleniumbase_lines.append(command)
            continue

        # Handle if/elif self.is_element_*(SELECTOR):  * = present/visible
        if not object_dict:
            data = re.match(
                r"""^(\s*)(\S*)\sself\.is_element_(\S*)"""
                r"""\((r?['"][\S\s]+['"])\):([\S\s]*)"""
                r"""$""",
                line,
            )
        else:
            data = re.match(
                r"""^(\s*)(\S*)\sself\.is_element_(\S*)"""
                r"""\(([\S]+)\):([\S\s]*)"""
                r"""$""",
                line,
            )
        if data:
            whitespace = data.group(1)
            if_type = data.group(2)
            by_type = data.group(3)
            selector = "%s" % data.group(4)
            selector = remove_extra_slashes(selector)
            page_selectors.append(selector)
            comments = data.group(5)
            command = """%s%s self.is_element_%s(%s):%s""" % (
                whitespace,
                if_type,
                by_type,
                selector,
                comments,
            )
            if selector_dict:
                if add_comments:
                    comments = "  # %s" % selector
                selector = optimize_selector(selector)
                if selector in selector_dict.keys():
                    selector_object = selector_dict[selector]
                    changed.append(selector_object.split(".")[0])
                    command = """%s%s self.is_element_%s(%s):%s""" % (
                        whitespace,
                        if_type,
                        by_type,
                        selector_object,
                        comments,
                    )
            if object_dict:
                if not add_comments:
                    comments = ""
                object_name = selector
                if object_name in object_dict.keys():
                    selector_object = object_dict[object_name]
                    changed.append(object_name.split(".")[0])
                    command = """%s%s self.is_element_%s(%s):%s""" % (
                        whitespace,
                        if_type,
                        by_type,
                        selector_object,
                        comments,
                    )
            seleniumbase_lines.append(command)
            continue

        # Handle if/elif self.is_selected(SELECTOR):
        if not object_dict:
            data = re.match(
                r"""^(\s*)(\S*)\sself\.is_selected"""
                r"""\((r?['"][\S\s]+['"])\):([\S\s]*)"""
                r"""$""",
                line,
            )
        else:
            data = re.match(
                r"""^(\s*)(\S*)\sself\.is_selected"""
                r"""\(([\S]+)\):([\S\s]*)"""
                r"""$""",
                line,
            )
        if data:
            whitespace = data.group(1)
            if_type = data.group(2)
            selector = "%s" % data.group(3)
            selector = remove_extra_slashes(selector)
            page_selectors.append(selector)
            comments = data.group(4)
            command = """%s%s self.is_selected(%s):%s""" % (
                whitespace,
                if_type,
                selector,
                comments,
            )
            if selector_dict:
                if add_comments:
                    comments = "  # %s" % selector
                selector = optimize_selector(selector)
                if selector in selector_dict.keys():
                    selector_object = selector_dict[selector]
                    changed.append(selector_object.split(".")[0])
                    command = """%s%s self.is_selected(%s):%s""" % (
                        whitespace,
                        if_type,
                        selector_object,
                        comments,
                    )
            if object_dict:
                if not add_comments:
                    comments = ""
                object_name = selector
                if object_name in object_dict.keys():
                    selector_object = object_dict[object_name]
                    changed.append(object_name.split(".")[0])
                    command = """%s%s self.is_selected(%s):%s""" % (
                        whitespace,
                        if_type,
                        selector_object,
                        comments,
                    )
            seleniumbase_lines.append(command)
            continue

        # Handle self.assert*(self.is_selected(SELECTOR))
        if not object_dict:
            data = re.match(
                r"""^(\s*)self\.assert(\S*)\(self\.is_selected"""
                r"""\((r?['"][\S\s]+['"])\)\)([\S\s]*)"""
                r"""$""",
                line,
            )
        else:
            data = re.match(
                r"""^(\s*)self\.assert(\S*)\(self\.is_selected"""
                r"""\(([\S]+)\)\)([\S\s]*)"""
                r"""$""",
                line,
            )
        if data:
            whitespace = data.group(1)
            a_type = data.group(2)
            selector = "%s" % data.group(3)
            selector = remove_extra_slashes(selector)
            page_selectors.append(selector)
            comments = data.group(4)
            command = """%sself.assert%s(self.is_selected(%s))%s""" % (
                whitespace,
                a_type,
                selector,
                comments,
            )
            if selector_dict:
                if add_comments:
                    comments = "  # %s" % selector
                selector = optimize_selector(selector)
                if selector in selector_dict.keys():
                    selector_object = selector_dict[selector]
                    changed.append(selector_object.split(".")[0])
                    command = """%sself.assert%s(self.is_selected(%s))%s""" % (
                        whitespace,
                        a_type,
                        selector_object,
                        comments,
                    )
            if object_dict:
                if not add_comments:
                    comments = ""
                object_name = selector
                if object_name in object_dict.keys():
                    selector_object = object_dict[object_name]
                    changed.append(object_name.split(".")[0])
                    command = """%sself.assert%s(self.is_selected(%s))%s""" % (
                        whitespace,
                        a_type,
                        selector_object,
                        comments,
                    )
            seleniumbase_lines.append(command)
            continue

        # Handle self.assert*(self.is_element_*(SELECTOR))
        if not object_dict:
            data = re.match(
                r"""^(\s*)self\.assert(\S*)\(self\.is_element_(\S*)"""
                r"""\((r?['"][\S\s]+['"])\)\)([\S\s]*)"""
                r"""$""",
                line,
            )
        else:
            data = re.match(
                r"""^(\s*)self\.assert(\S*)\(self\.is_element_(\S*)"""
                r"""\(([\S]+)\)\)([\S\s]*)"""
                r"""$""",
                line,
            )
        if data:
            whitespace = data.group(1)
            a_type = data.group(2)
            v_type = data.group(3)
            selector = "%s" % data.group(4)
            selector = remove_extra_slashes(selector)
            page_selectors.append(selector)
            comments = data.group(5)
            command = """%sself.assert%s(self.is_element_%s(%s))%s""" % (
                whitespace,
                a_type,
                v_type,
                selector,
                comments,
            )
            if selector_dict:
                if add_comments:
                    comments = "  # %s" % selector
                selector = optimize_selector(selector)
                if selector in selector_dict.keys():
                    selector_object = selector_dict[selector]
                    changed.append(selector_object.split(".")[0])
                    command = "%sself.assert%s(self.is_element_%s(%s))%s" % (
                        whitespace,
                        a_type,
                        v_type,
                        selector_object,
                        comments,
                    )
            if object_dict:
                if not add_comments:
                    comments = ""
                object_name = selector
                if object_name in object_dict.keys():
                    selector_object = object_dict[object_name]
                    changed.append(object_name.split(".")[0])
                    command = "%sself.assert%s(self.is_element_%s(%s))%s" % (
                        whitespace,
                        a_type,
                        v_type,
                        selector_object,
                        comments,
                    )
            seleniumbase_lines.append(command)
            continue

        # Handle self.set_attribute(SELECTOR, ATTRIBUTE, VALUE)
        if not object_dict:
            data = re.match(
                r"""^(\s*)self\.set_attribute"""
                r"""\((r?['"][\S\s]+['"])"""
                r""",\s?([\S\s]+),\s?([\S\s]+)\)([\S\s]*)"""
                r"""$""",
                line,
            )
        else:
            data = re.match(
                r"""^(\s*)self\.set_attribute"""
                r"""\(([\S]+),\s?([\S\s]+),\s?([\S\s]+)\)([\S\s]*)"""
                r"""$""",
                line,
            )
        if data:
            whitespace = data.group(1)
            selector = "%s" % data.group(2)
            selector = remove_extra_slashes(selector)
            page_selectors.append(selector)
            attribute = data.group(3)
            value = data.group(4)
            comments = data.group(5)
            command = """%sself.set_attribute(%s, %s, %s)%s""" % (
                whitespace,
                selector,
                attribute,
                value,
                comments,
            )
            if selector_dict:
                if add_comments:
                    comments = "  # %s" % selector
                selector = optimize_selector(selector)
                if selector in selector_dict.keys():
                    selector_object = selector_dict[selector]
                    changed.append(selector_object.split(".")[0])
                    command = """%sself.set_attribute(%s, %s, %s)%s""" % (
                        whitespace,
                        selector_object,
                        attribute,
                        value,
                        comments,
                    )
            if object_dict:
                if not add_comments:
                    comments = ""
                object_name = selector
                if object_name in object_dict.keys():
                    selector_object = object_dict[object_name]
                    changed.append(object_name.split(".")[0])
                    command = """%sself.set_attribute(%s, %s, %s)%s""" % (
                        whitespace,
                        selector_object,
                        attribute,
                        value,
                        comments,
                    )
            seleniumbase_lines.append(command)
            continue

        # Handle self.set_attributes(SELECTOR, ATTRIBUTE, VALUE)
        if not object_dict:
            data = re.match(
                r"""^(\s*)self\.set_attributes"""
                r"""\((r?['"][\S\s]+['"]),"""
                r"""\s?([\S\s]+),\s?([\S\s]+)\)([\S\s]*)"""
                r"""$""",
                line,
            )
        else:
            data = re.match(
                r"""^(\s*)self\.set_attributes"""
                r"""\(([\S]+),\s?([\S\s]+),\s?([\S\s]+)\)([\S\s]*)"""
                r"""$""",
                line,
            )
        if data:
            whitespace = data.group(1)
            selector = "%s" % data.group(2)
            selector = remove_extra_slashes(selector)
            page_selectors.append(selector)
            attribute = data.group(3)
            value = data.group(4)
            comments = data.group(5)
            command = """%sself.set_attributes(%s, %s, %s)%s""" % (
                whitespace,
                selector,
                attribute,
                value,
                comments,
            )
            if selector_dict:
                if add_comments:
                    comments = "  # %s" % selector
                selector = optimize_selector(selector)
                if selector in selector_dict.keys():
                    selector_object = selector_dict[selector]
                    changed.append(selector_object.split(".")[0])
                    command = """%sself.set_attributes(%s, %s, %s)%s""" % (
                        whitespace,
                        selector_object,
                        attribute,
                        value,
                        comments,
                    )
            if object_dict:
                if not add_comments:
                    comments = ""
                object_name = selector
                if object_name in object_dict.keys():
                    selector_object = object_dict[object_name]
                    changed.append(object_name.split(".")[0])
                    command = """%sself.set_attributes(%s, %s, %s)%s""" % (
                        whitespace,
                        selector_object,
                        attribute,
                        value,
                        comments,
                    )
            seleniumbase_lines.append(command)
            continue

        # Handle VAR = self.get_attribute(SELECTOR, ATTRIBUTE)
        if not object_dict:
            data = re.match(
                r"""^(\s*)(\S*)\s?=\s?self\.get_attribute"""
                r"""\((r?['"][\S\s]+['"]),\s?(['"][\S\s]+['"])\)([\S\s]*)"""
                r"""$""",
                line,
            )
        else:
            data = re.match(
                r"""^(\s*)(\S*)\s?=\s?self\.get_attribute"""
                r"""\(([\S]+),\s?(['"][\S\s]+['"])\)([\S\s]*)"""
                r"""$""",
                line,
            )
        if data:
            whitespace = data.group(1)
            var_name = data.group(2)
            selector = "%s" % data.group(3)
            selector = remove_extra_slashes(selector)
            page_selectors.append(selector)
            attribute = data.group(4)
            comments = data.group(5)
            command = """%s%s = self.get_attribute(%s, %s)%s""" % (
                whitespace,
                var_name,
                selector,
                attribute,
                comments,
            )
            if selector_dict:
                if add_comments:
                    comments = "  # %s" % selector
                selector = optimize_selector(selector)
                if selector in selector_dict.keys():
                    selector_object = selector_dict[selector]
                    changed.append(selector_object.split(".")[0])
                    command = """%s%s = self.get_attribute(%s, %s)%s""" % (
                        whitespace,
                        var_name,
                        selector_object,
                        attribute,
                        comments,
                    )
            if object_dict:
                if not add_comments:
                    comments = ""
                object_name = selector
                if object_name in object_dict.keys():
                    selector_object = object_dict[object_name]
                    changed.append(object_name.split(".")[0])
                    command = """%s%s = self.get_attribute(%s, %s)%s""" % (
                        whitespace,
                        var_name,
                        selector_object,
                        attribute,
                        comments,
                    )
            seleniumbase_lines.append(command)
            continue

        # Handle VAR = self.get_text(SELECTOR)
        if not object_dict:
            data = re.match(
                r"""^(\s*)(\S*)\s?=\s?self\.get_text"""
                r"""\((r?['"][\S\s]+['"])\)([\S\s]*)"""
                r"""$""",
                line,
            )
        else:
            data = re.match(
                r"""^(\s*)(\S*)\s?=\s?self\.get_text"""
                r"""\(([\S]+)\)([\S\s]*)"""
                r"""$""",
                line,
            )
        if data:
            whitespace = data.group(1)
            var_name = data.group(2)
            selector = "%s" % data.group(3)
            selector = remove_extra_slashes(selector)
            page_selectors.append(selector)
            comments = data.group(4)
            command = """%s%s = self.get_text(%s)%s""" % (
                whitespace,
                var_name,
                selector,
                comments,
            )
            if selector_dict:
                if add_comments:
                    comments = "  # %s" % selector
                selector = optimize_selector(selector)
                if selector in selector_dict.keys():
                    selector_object = selector_dict[selector]
                    changed.append(selector_object.split(".")[0])
                    command = """%s%s = self.get_text(%s)%s""" % (
                        whitespace,
                        var_name,
                        selector_object,
                        comments,
                    )
            if object_dict:
                if not add_comments:
                    comments = ""
                object_name = selector
                if object_name in object_dict.keys():
                    selector_object = object_dict[object_name]
                    changed.append(object_name.split(".")[0])
                    command = """%s%s = self.get_text(%s)%s""" % (
                        whitespace,
                        var_name,
                        selector_object,
                        comments,
                    )
            seleniumbase_lines.append(command)
            continue

        # Handle if VAR [in|not in] self.get_text(SELECTOR):
        if not object_dict:
            data = re.match(
                r"""^(\s*)if\s(\S*\s?\S*)\sin\s?self\.get_text"""
                r"""\((r?['"][\S\s]+['"])\):([\S\s]*)"""
                r"""$""",
                line,
            )
        else:
            data = re.match(
                r"""^(\s*)if\s(\S*\s?\S*)\sin\s?self\.get_text"""
                r"""\(([\S]+)\):([\S\s]*)"""
                r"""$""",
                line,
            )
        if data:
            whitespace = data.group(1)
            var_prefix = data.group(2)
            selector = "%s" % data.group(3)
            selector = remove_extra_slashes(selector)
            page_selectors.append(selector)
            comments = data.group(4)
            command = """%sif %s in self.get_text(%s):%s""" % (
                whitespace,
                var_prefix,
                selector,
                comments,
            )
            if selector_dict:
                if add_comments:
                    comments = "  # %s" % selector
                selector = optimize_selector(selector)
                if selector in selector_dict.keys():
                    selector_object = selector_dict[selector]
                    changed.append(selector_object.split(".")[0])
                    command = """%sif %s in self.get_text(%s):%s""" % (
                        whitespace,
                        var_prefix,
                        selector_object,
                        comments,
                    )
            if object_dict:
                if not add_comments:
                    comments = ""
                object_name = selector
                if object_name in object_dict.keys():
                    selector_object = object_dict[object_name]
                    changed.append(object_name.split(".")[0])
                    command = """%sif %s in self.get_text(%s):%s""" % (
                        whitespace,
                        var_prefix,
                        selector_object,
                        comments,
                    )
            seleniumbase_lines.append(command)
            continue

        # Handle self.select_option_by_*(SELECTOR, TEXT)  * = index/value/text
        if not object_dict:
            data = re.match(
                r"""^(\s*)self\.select_option_by_(\S*)"""
                r"""\((r?['"][\S\s]+['"]),\s?([\S\s]+)\)([\S\s]*)"""
                r"""$""",
                line,
            )
        else:
            data = re.match(
                r"""^(\s*)self\.select_option_by_(\S*)"""
                r"""\(([\S]+),\s?([\S\s]+)\)([\S\s]*)"""
                r"""$""",
                line,
            )
        if data:
            whitespace = data.group(1)
            by_type = data.group(2)
            selector = "%s" % data.group(3)
            selector = remove_extra_slashes(selector)
            page_selectors.append(selector)
            text = data.group(4)
            comments = data.group(5)
            command = """%sself.select_option_by_%s(%s, %s)%s""" % (
                whitespace,
                by_type,
                selector,
                text,
                comments,
            )
            if selector_dict:
                if add_comments:
                    comments = "  # %s" % selector
                selector = optimize_selector(selector)
                if selector in selector_dict.keys():
                    selector_object = selector_dict[selector]
                    changed.append(selector_object.split(".")[0])
                    command = """%sself.select_option_by_%s(%s, %s)%s""" % (
                        whitespace,
                        by_type,
                        selector_object,
                        text,
                        comments,
                    )
            if object_dict:
                if not add_comments:
                    comments = ""
                object_name = selector
                if object_name in object_dict.keys():
                    selector_object = object_dict[object_name]
                    changed.append(object_name.split(".")[0])
                    command = """%sself.select_option_by_%s(%s, %s)%s""" % (
                        whitespace,
                        by_type,
                        selector_object,
                        text,
                        comments,
                    )
            seleniumbase_lines.append(command)
            continue

        # seleniumbase_lines.append("### " + line)  # untouched lines (Debug)
        seleniumbase_lines.append(line)
        continue

    return seleniumbase_lines, page_selectors, changed


def extract_objects():
    main(shell_command="extract-objects")


def inject_objects():
    main(shell_command="inject-objects")


def objectify():
    main(shell_command="objectify")


def revert_objects():
    main(shell_command="revert-objects")


def main(shell_command):
    expected_arg = "[A SeleniumBase Python file]"
    num_args = len(sys.argv)
    command_args = sys.argv[2:]

    add_comments = False
    if shell_command == "objectify" or (
        shell_command == "inject-objects"
        or (shell_command == "revert-objects")
    ):
        if len(command_args) >= 2:
            options = command_args[1:]
            for option in options:
                if option == "-c" or option == "--comments":
                    add_comments = True
                else:
                    invalid_run_command(shell_command)

    if (
        sys.argv[0].split("/")[-1] == "seleniumbase"
        or (sys.argv[0].split("\\")[-1] == "seleniumbase")
        or (sys.argv[0].split("/")[-1] == "sbase")
        or (sys.argv[0].split("\\")[-1] == "sbase")
    ):
        if num_args < 3:
            invalid_run_command(shell_command)
        elif num_args > 3:
            if shell_command == "extract-objects":
                invalid_run_command(shell_command)
            else:
                pass
        else:
            pass
    else:
        invalid_run_command(shell_command)

    seleniumbase_file = command_args[0]
    if not seleniumbase_file.endswith(".py"):
        raise Exception(
            "\n\n`%s` is not a Python file!\n\n"
            "Expecting: %s\n" % (seleniumbase_file, expected_arg)
        )

    with open(seleniumbase_file, "r", encoding="utf-8") as f:
        all_code = f.read()
    if "def test_" not in all_code:
        raise Exception(
            "\n\n`%s` is not a valid SeleniumBase unittest file!\n"
            "\nExpecting: %s\n" % (seleniumbase_file, expected_arg)
        )
    code_lines = all_code.split("\n")
    seleniumbase_lines, page_selectors, changed = process_test_file(code_lines)
    var_names, existing_selectors, selector_list_dict = scan_objects_file()
    new_page_selectors = []

    for selector in page_selectors:
        selector = optimize_selector(selector)
        if selector not in existing_selectors:
            new_page_selectors.append(selector)
            var_name = get_next_var_name(var_names)
            var_names.append(var_name)
            selector_list_dict["Page"].append((var_name, selector))
            existing_selectors.append(selector)

    # print(new_page_selectors)  # (For debugging)
    # print(selector_list_dict)  # (For debugging)

    if shell_command == "extract-objects" or shell_command == "objectify":
        create_objects_file(selector_list_dict)

    if shell_command == "extract-objects":
        print("")
        return

    selector_dict = {}  # Key: selector, Value: object
    object_dict = {}  # Key: object, Value: selector
    for key in selector_list_dict.keys():
        for pair in selector_list_dict[key]:
            selector_dict[pair[1]] = "%s.%s" % (str(key), str(pair[0]))
            object_name = "%s.%s" % (str(key), str(pair[0]))
            object_dict[object_name] = pair[1]

    good_sel_dict = {}
    aa, bb, cc = scan_objects_file()
    for s_key in selector_dict.keys():
        if s_key in bb:
            good_sel_dict[s_key] = selector_dict[s_key]

    if shell_command == "inject-objects" or shell_command == "objectify":
        seleniumbase_lines, page_selectors, changed = process_test_file(
            code_lines, selector_dict=good_sel_dict, add_comments=add_comments
        )
        added_classes = []
        for item in changed:
            if item not in added_classes:
                added_classes.append(item)
        for line in seleniumbase_lines:
            if "from .page_objects import" in line:
                token = line.split("from .page_objects import ")[1].strip()
                if token in added_classes:
                    # Don't import page_objects classes if already imported
                    added_classes.remove(token)
        if added_classes:
            sb_lines = []
            fit_in = False
            for line in seleniumbase_lines:
                if line.startswith("from") and "import" in line and not fit_in:
                    fit_in = True
                    for add_me in added_classes:
                        import_line = "from .page_objects import %s" % add_me
                        sb_lines.append(import_line)
                sb_lines.append(line)
            seleniumbase_lines = sb_lines

    if shell_command == "revert-objects":
        seleniumbase_lines, page_selectors, changed = process_test_file(
            code_lines, object_dict=object_dict, add_comments=add_comments
        )
        removed_classes = []
        for item in changed:
            if item not in removed_classes:
                removed_classes.append(item)
        if removed_classes:
            sb_lines = []
            for line in seleniumbase_lines:
                if "from .page_objects import" in line:
                    token = line.split("from .page_objects import ")[1].strip()
                    if token in removed_classes:
                        continue
                sb_lines.append(line)
            seleniumbase_lines = sb_lines

    seleniumbase_code = ""
    for line in seleniumbase_lines:
        seleniumbase_code += line
        seleniumbase_code += "\n"
    seleniumbase_code = seleniumbase_code[:-1]
    # print (seleniumbase_code)  # (For debugging)

    # Create SeleniumBase test file
    base_file_name = seleniumbase_file.split(".py")[0]
    converted_file_name = base_file_name + ".py"  # Change end to make a copy
    out_file = codecs.open(converted_file_name, "w+", encoding="utf-8")
    out_file.writelines(seleniumbase_code)
    out_file.close()
    print('\n>>> ["%s"] was updated!\n' % converted_file_name)


if __name__ == "__main__":
    invalid_objectify_run_command()
